package EA.testproblems;
import EA.*;

/**
This testproblem is a simple problem for initial tuning of multimodal 
optimization algorithms. <br><br>

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">Ursem multimodal 5</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">Waves (10 peaks)&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Provides several things such as asymmetric landscape, 
different heights, ridgelike peaks, etc.</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">(0.3x)<sup>3</sup> - (y<sup>2</sup> - 4.5y<sup>2</sup>)xy - 
4.7cos(3x - y<sup>2</sup>(2+x))sin(2.5pi*x)</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/ursemmultimodal5.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/ursemmultimodal5_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-0.9:1.2]&nbsp;&nbsp;y = [-1.2:1.2] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Maximization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maximas:</b></td>
  <td valign="top">10</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minimas:</b></td>
  <td valign="top">10</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum radius:</b></td>
  <td valign="top">0.15
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optimum descriptions:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optimums:</b></td>
  <td valign="top">
  LMAX(-0.6093621544,0.8072238867),
  LMAX(-0.6056894935,-1.177561934),
  LMAX(-0.1726942583,0),
  LMAX(0.1618378139,-1.2),
  LMAX(0.2082970563,1.2),
  LMAX(0.617713031,0.8942768279),
  LMAX(1.006280385,0),
  LMAX(1.2, 1.2}) 
  LMAX(1.011778846,1.2),
  LMAX(0.5865040883,-0.7767035418),
  LMAX(1.006280385,0),
  LMIN(-0.9,1.2),
  LMIN(0.4598623207,0),
  LMIN(-0.1843720315,-1.16861766),
  LMIN(-0.2190055519,1.2),
  LMIN(0.5929345995,-1.2),
  LMIN(0.1963055554,0.4955736915),
  LMIN(0.204521087,-0.551617037)}
  LMIN(1.030103196, -1.078606537),
  LMIN(0.68133663664,0),
  LMIN(0.9766457958,0.930241037)

<br><font size=1>Capital letters 
means that the precise optimum is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 40<br>
  set view 70,15<br>
splot [-0.9:1.2] [-1.2:1.2] (0.3*x)**3  + 3.5*y**3*x - 4.7*cos(3*x - y**2*(2+x))*sin(2.5*pi*x)
</td>

</tr>

</table>

*/
public class UrsemMultimodal5 extends NumericalProblem
{

  // Easier way to build max
  private double[][] lmax =  {{-0.6093621544,0.8072238867},
			      {-0.6056894935,-1.177561934},
			      {-0.1726942583,0},
			      {0.1618378139,-1.2},
			      {0.2082970563,1.2},
			      {0.617713031,0.8942768279},
			      {1.006280385,0},
			      {1.2, 1.2}, 
			      {1.011778846,1.2},
			      {0.5865040883,-0.7767035418},
			      {1.006280385,0}};
  private double[][] lmin =  {{-0.9,1.2},
			      {0.4598623207,0},
			      {-0.1843720315,-1.16861766},
			      {-0.2190055519,1.2},
			      {0.5929345995,-1.2},
			      {0.1963055554,0.4955736915},
			      {0.204521087,-0.5516170370},
			      {1.030103196, -1.078606537},
			      {0.68133663664,0},
			      {0.9766457958,0.9302410372}};

  public UrsemMultimodal5()
    {
      super();

      double[] optimums;

      name = "Ursem Multimodal 5";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		  return Math.pow((0.3*realpos[0]),3) - (realpos[1]*realpos[1] - 4.5*realpos[1]*realpos[1])*realpos[0]*realpos[1] - 4.7*Math.cos(3*realpos[0] - realpos[1]*realpos[1]*(2+realpos[0]))*Math.sin(2.5*Math.PI*realpos[0]);

	      };
	  };

      dimensions = 2;
      ismaximization = true;
      optimumradius = 0.15;

      intervals = new Interval[2];
      intervals[0] = new Interval(-0.9,1.2);
      intervals[1] = new Interval(-1.2,1.2);

      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (int i=0;i<lmax.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmax[i][0];
	optimums[1] = lmax[i][1];
	knownmaxima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (int i=0;i<lmin.length;i++) {
	optimums = new double[dimensions];
	optimums[0] = lmin[i][0];
	optimums[1] = lmin[i][1];
	knownminima[i] = new NumericalOptimum(optimums, objectivefunction.calcFitness(optimums), false, false, i);
      }
    }
}
